'''
Created on 10 juin 2013

@author: Nils Amiet
'''

import threading

from ITInfluence.models import User, Friendship
from ITInfluence.twitter import TwitterREST

rest = TwitterREST()

def collectRequest(query):
    userRequestPerMinute = 1
    followersPerRequest = 5000
    
    val = User.objects.raw(query, [followersPerRequest])
    req = val[0].req
    try:
        minutes = req / userRequestPerMinute
        hours = minutes / 60
        days = hours / 24
    
        return days, hours, minutes
    except:
        return 0, 0, 0

def getTotalTimeToCollectFollowers():
    '''Returns an estimation of the time required to collect all the followers for the users in the database'''
    
    query = """
    SELECT id, sum(IF(followers_count, ceiling(followers_count/%s), 1)) as req
    FROM ITInfluence_user
    WHERE followers_count > 0
    """
    return collectRequest(query)
    
def getRemainingTimeToCollectFollowers():
    '''Returns an estimation of the time required to collect the followers for the users that we didnt get the followers yet.'''
    
    query = """
    SELECT id, sum(IF(followers_count, ceiling(followers_count/%s), 1)) as req
    FROM ITInfluence_user
    WHERE followers_ready=0
    """
    return collectRequest(query)
    
def collectFollowersData():
    '''Collect the followers for all users in the database that have not their followers collected yet'''
    print("Started collecting followers.")
    users = User.objects.all().filter(followers_ready=False).filter(followers_count__gte=1)
    
    for user in users:
        # stop collecting if asked
        if not rest.isCollectingFollowers:
            return
        followers = rest.getFollowers(int(user.id), getAll=True)  # rate limited 15 every 15 minutes
        if followers is None:
            print("Stopped collecting followers.")
            return  # stop collecting
        print("Collected %s followers" % len(followers))
        
        print("Inserting collected followers into database...")
        for follower in followers:
            # stop collecting if asked
            if not rest.isCollectingFollowers:
                print("Stopped collecting followers.")
                return
            
            source = user
            try:
                destination = User.objects.get(id=follower)
            except:
#                destination = createUser(follower)
                destination = User(id=follower)
                destination.followers_ready = True
                destination.user_ready = False
                destination.statuses_count = 0
                destination.friends_count = 0
                destination.followers_count = 0
                
                destination.save()
            
            friendship = Friendship(user=destination, followed_user=source)
            friendship.save()
        
        user.followers_ready = True
        user.save()
        print("...done inserting followers for this user!")
    print("Stopped collecting followers.")
    rest.isCollectingFollowers = False
        
def runFollowersCollection():
    thread = threading.Thread(target=collectFollowersData)
    thread.daemon = True
    thread.start()
    
def toggleFollowersCollection():
    rest.isCollectingFollowers = not rest.isCollectingFollowers
        
    if rest.isCollectingFollowers:
        runFollowersCollection()
            
def createUser(userId):
    user = rest.getUser(userId)  # rate limited 180 every 15 minutes
    
    return user
